#pragma once

#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>

// 序列化后，添加报头
// "len"\r\n"{json}"\r\n
static const std::string sep = "\r\n";
std::string Encode(const std::string &jsonstr)
{
    int len = jsonstr.size();
    std::string lenstr = std::to_string(len);
    return lenstr + sep + jsonstr + sep;
}

// 解析报头，取下有效载荷
// "le
// "len"\r\n"{jso
// "len"\r\n"{json}"\r\n
// "len"\r\n"{json}"\r\n"len"\r\n"{json}"\r\n
std::string Decode(std::string &packageStream)
{
    // 分析
    size_t pos = packageStream.find(sep);
    if (pos == std::string::npos) return std::string(); // 报文不全，甚至没有len
    // 取得 Json 串的长度
    std::string lenstr = packageStream.substr(0, pos);
    int len = std::stoi(lenstr);
    // 计算报文的总长度
    int total = lenstr.size() + len + sep.size()*2;
    // 报文长度不够，返回
    if (packageStream.size() < total) return std::string();

    // 到这里，至少有一条有效报文，提取有效载荷 json 串
    std::string jsonstr = packageStream.substr(pos + sep.size(), len);
    // 删除读取完毕的报文
    packageStream.erase(0, total);
    return jsonstr;
}

class Request
{
public:
    Request(){}
    Request(int x, int y, char ope)
        : _x(x), _y(y), _opera(ope)
    {}
    ~Request(){}
    
    // 序列化
    bool Serialize(std::string *out)
    {
        Json::Value root;
        root["x"] = _x;
        root["y"] = _y;
        root["operator"] = _opera;

        // 序列化
        Json::FastWriter writer;
        *out = writer.write(root);

        return true;
    }
    // 反序列化
    bool Deserialize(const std::string &in)
    {
        Json::Value root;
        Json::Reader reader;
        reader.parse(in, root);

        _x = root["x"].asInt();
        _y = root["y"].asInt();
        _opera = root["operator"].asInt(); // 字符也是使用int

        return true;
    }

    void SetVal(int x, int y, char oper)
    {
        _x = x;
        _y = y;
        _opera = oper;
    }
    
public:
    int _x;
    int _y;
    char _opera; // + - * / %
};

class Response
{
public:
    Response():_result(0), _code(0), _desc("sucess")
    {}
    ~Response(){}

    // 序列化
    bool Serialize(std::string *out)
    {
        Json::Value root;
        root["result"] = _result;
        root["code"] = _code;
        root["desc"] = _desc;

        // 序列化
        Json::FastWriter writer;
        *out = writer.write(root);

        return true;
    }
    // 反序列化
    bool Deserialize(const std::string &in)
    {
        Json::Value root;
        Json::Reader reader;
        reader.parse(in, root);

        _result = root["result"].asInt();
        _code = root["code"].asInt();
        _desc = root["desc"].asString();

        return true;
    }

    // 打印
    void PrintRet()
    {
        std::cout << "result: " << _result << ", code: " << _code << ", desc: " << _desc << std::endl;
    }
public:
    int _result;
    int _code; // 0:sucess, 1: div 0, 2: mod 0, 3: illegal
    std::string _desc;
};

// 工厂模式，用于创建类对象
class Factor
{
public:
    static std::shared_ptr<Request> BuildRequest()
    {
        return std::make_shared<Request>();
    }

    static std::shared_ptr<Response> BuildResponse()
    {
        return std::make_shared<Response>();
    }
};